<!doctype html>




<html class="theme-next pisces" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />












  
  
    
  
  <link href="//cdn.staticfile.org/fancybox/2.1.5/jquery.fancybox.min.css" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  
    
      
    

    
  

  

  
    
      
    

    
  

  
    
      
    

    
  

  
    
    
    <link href="//fonts.lug.ustc.edu.cn/css?family=Monda:300,300italic,400,400italic,700,700italic|Roboto Slab:300,300italic,400,400italic,700,700italic|Lobster Two:300,300italic,400,400italic,700,700italic|PT Mono:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






  

<link href="//cdn.staticfile.org/font-awesome/4.6.2/css/font-awesome.min.css" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.0" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="Web,JavaScript," />








  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.1.0" />






<meta name="description" content="JSONJSON（JavaScript Object Notation，JavaScript 对象表示法）2006 年，Douglas Crockford 把JSON（JavaScript Object Notation，JavaScript 对象表示法）作为IETFRFC 4627 提交给IETF。Crockford 认为与XML相比，JSON 是在JavaScript中读写结构化数据的更好的方">
<meta property="og:type" content="article">
<meta property="og:title" content="《 JavaScript 高级程序设计》备忘-第二十章">
<meta property="og:url" content="http://codingme.xyz/2016/11/03/javascript-note-20/index.html">
<meta property="og:site_name" content="CodingMe">
<meta property="og:description" content="JSONJSON（JavaScript Object Notation，JavaScript 对象表示法）2006 年，Douglas Crockford 把JSON（JavaScript Object Notation，JavaScript 对象表示法）作为IETFRFC 4627 提交给IETF。Crockford 认为与XML相比，JSON 是在JavaScript中读写结构化数据的更好的方">
<meta property="og:updated_time" content="2016-11-04T08:04:42.300Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="《 JavaScript 高级程序设计》备忘-第二十章">
<meta name="twitter:description" content="JSONJSON（JavaScript Object Notation，JavaScript 对象表示法）2006 年，Douglas Crockford 把JSON（JavaScript Object Notation，JavaScript 对象表示法）作为IETFRFC 4627 提交给IETF。Crockford 认为与XML相比，JSON 是在JavaScript中读写结构化数据的更好的方">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Pisces',
    sidebar: {"position":"right","display":"post"},
    fancybox: true,
    motion: false,
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://codingme.xyz/2016/11/03/javascript-note-20/"/>





  <title> 《 JavaScript 高级程序设计》备忘-第二十章 | CodingMe </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  










  
  
    
  

  <div class="container one-collumn sidebar-position-right page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-meta ">
  

  <div class="custom-logo-site-title">
    <a href="/"  class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <span class="site-title">CodingMe</span>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>
  <p class="site-subtitle"></p>
</div>

<div class="site-nav-toggle">
  <button>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
  </button>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      

      
        <li class="menu-item menu-item-search">
          
            <a href="javascript:;" class="popup-trigger">
          
            
              <i class="menu-item-icon fa fa-search fa-fw"></i> <br />
            
            搜索
          </a>
        </li>
      
    </ul>
  

  
    <div class="site-search">
      
  <div class="popup">
 <span class="search-icon fa fa-search"></span>
 <input type="text" id="local-search-input">
 <div id="local-search-result"></div>
 <span class="popup-btn-close">close</span>
</div>


    </div>
  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
  <link itemprop="mainEntityOfPage" href="http://codingme.xyz/2016/11/03/javascript-note-20/">

  <span style="display:none" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <meta itemprop="name" content="Huang SJ">
    <meta itemprop="description" content="">
    <meta itemprop="image" content="/uploads/avatar.jpg">
  </span>

  <span style="display:none" itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
    <meta itemprop="name" content="CodingMe">
    <span style="display:none" itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
      <img style="display:none;" itemprop="url image" alt="CodingMe" src="">
    </span>
  </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                《 JavaScript 高级程序设计》备忘-第二十章
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            

            

            
          </span>

          

          
            
          

          

          
          

          

          

        </div>
      </header>
    


    <div class="post-body" itemprop="articleBody">

      
      

      
        <h1 id="JSON"><a href="#JSON" class="headerlink" title="JSON"></a>JSON</h1><p>JSON（JavaScript Object Notation，JavaScript 对象表示法）<br>2006 年，Douglas Crockford 把JSON（JavaScript Object Notation，JavaScript 对象表示法）作为IETFRFC 4627 提交给IETF。<br>Crockford 认为与XML相比，JSON 是在JavaScript中读写结构化数据的更好的方式。因为可以把JSON 直接传给eval()，而且不必创建DOM 对象。</p>
<p>关于JSON，最重要的是要理解它是一种<strong>数据格式</strong>，不是一种编程语言。虽然具有相同的语法形式，但JSON 并不从属于JavaScript。<br>而且，并不是只有JavaScript 才使用JSON，毕竟JSON 只是一种数据格式。很多编程语言都有针对JSON 的解析器和序列化器。</p>
<h2 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h2><p>JSON 的语法可以表示以下三种类型的值。</p>
<ul>
<li>简单值：使用与JavaScript 相同的语法，可以在JSON 中表示字符串、数值、布尔值和null。但JSON 不支持JavaScript 中的特殊值undefined。</li>
<li>对象：对象作为一种复杂数据类型，表示的是一组无序的键值对儿。而每个键值对儿中的值可以是简单值，也可以是复杂数据类型的值。</li>
<li>数组：数组也是一种复杂数据类型，表示一组有序的值的列表，可以通过数值索引来访问其中的值。数组的值也可以是任意类型——简单值、对象或数组。</li>
</ul>
<p>JSON 不支持变量、函数或对象实例，它就是一种表示结构化数据的格式，虽然与JavaScript 中表示数据的某些语法相同，但它并不局限JavaScript 的范畴。</p>
<h3 id="简单值"><a href="#简单值" class="headerlink" title="简单值"></a>简单值</h3><p>JavaScript 字符串与JSON 字符串的最大区别在于，JSON 字符串必须使用双引号（单引号会导致语法错误）。<br><code>&quot;Hello world!&quot;</code><br>布尔值和null 也是有效的JSON 形式。<br>但是，在实际应用中，JSON 更多地用来表示更复杂的数据结构，而简单值只是整个数据结构中的一部分。<br><a id="more"></a></p>
<h3 id="对象"><a href="#对象" class="headerlink" title="对象"></a>对象</h3><p>JSON 中的对象与JavaScript 字面量稍微有一些不同。<br>一个JavaScript 中的对象字面量：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> person = &#123;</div><div class="line">    name: <span class="string">"Nicholas"</span>,</div><div class="line">    age: <span class="number">29</span></div><div class="line">&#125;;</div></pre></td></tr></table></figure>
<p>JSON 中的对象要求给属性加引号。实际上，在JavaScript 中，前面的对象字面量完全可以写成下面这样：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> object = &#123;</div><div class="line">    <span class="string">"name"</span>: <span class="string">"Nicholas"</span>,</div><div class="line">    <span class="string">"age"</span>: <span class="number">29</span></div><div class="line">&#125;;</div></pre></td></tr></table></figure>
<p>JSON 表示上述对象的方式如下：</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">&#123;</div><div class="line">    <span class="attr">"name"</span>: <span class="string">"Nicholas"</span>,</div><div class="line">    <span class="attr">"age"</span>: <span class="number">29</span></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>与JavaScript 的对象字面量相比，JSON 对象有两个地方不一样。<br>首先，没有声明变量（JSON 中没有变量的概念）。<br>其次，没有末尾的分号（因为这不是JavaScript 语句，所以不需要分号）。<br><strong>对象的属性必须加双引号，这在JSON 中是必需的。</strong><br>属性的值可以是简单值，也可以是复杂类型值。</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">&#123;</div><div class="line">    <span class="attr">"name"</span>: <span class="string">"Nicholas"</span>,</div><div class="line">    <span class="attr">"age"</span>: <span class="number">29</span>,</div><div class="line">    <span class="attr">"school"</span>: &#123;</div><div class="line">        <span class="attr">"name"</span>: <span class="string">"Merrimack College"</span>,</div><div class="line">        <span class="attr">"location"</span>: <span class="string">"North Andover, MA"</span></div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>与JavaScript 不同，JSON 中对象的属性名任何时候都必须加双引号。<br>手工编写JSON 时，忘了给对象属性名加双引号或者把双引号写成单引号都是常见的错误。</p>
<h3 id="数组"><a href="#数组" class="headerlink" title="数组"></a>数组</h3><p>JSON 数组采用的就是JavaScript 中的数组字面量形式。<br>JavaScript 中的数组字面量：<code>var values = [25, &quot;hi&quot;, true];</code><br>JSON 中:<code>[25, &quot;hi&quot;, true]</code><br>JSON 数组也没有变量和分号。<br>把数组和对象结合起来，可以构成更复杂的数据集合。</p>
<p>对象和数组通常是JSON 数据结构的最外层形式（当然，这不是强制规定的），利用它们能够创造出各种各样的数据结构。</p>
<h2 id="解析与序列化"><a href="#解析与序列化" class="headerlink" title="解析与序列化"></a>解析与序列化</h2><p>JSON 之所以流行的一个原因是，可以把JSON 数据结构解析为有用的JavaScript 对象。<br>与XML 数据结构要解析成DOM 文档而且从中提取数据极为麻烦相比，JSON 可以解析为JavaScript 对象的优势极其明显。<br>在解析为JavaScript 对象后:<code>books[2].title</code><br>在DOM结构中查找数据的代码：<code>doc.getElementsByTagName(&quot;book&quot;)[2].getAttribute(&quot;title&quot;)</code></p>
<p>从此以后，JSON 就成了Web 服务开发中交换数据的事实标准。</p>
<h3 id="JSON对象"><a href="#JSON对象" class="headerlink" title="JSON对象"></a>JSON对象</h3><p>早期的JSON 解析器基本上就是使用JavaScript 的eval()函数。<br>由于JSON 是JavaScript 语法的子集，因此eval()函数可以解析、解释并返回JavaScript 对象和数组。<br>ECMAScript 5 对解析JSON 的行为进行规范，定义了全局对象JSON。<br>支持这个对象的浏览器有IE 8+、Firefox 3.5+、Safari 4+、Chrome和Opera 10.5+。</p>
<p>对于较早版本的浏览器，可以使用一个shim：<a href="https://github.com/douglascrockford/JSON-js。" target="_blank" rel="external">https://github.com/douglascrockford/JSON-js。</a></p>
<p>(shim和polyfill的区别：<br>shim 是一个库,它将一个新的API引入到一个旧的环境中,而且仅靠旧环境中已有的手段实现;<br>polyfill就是一个用在浏览器API上的shim。<br>举例：<br>es5-shim是一个shim(而不是polyfill),它在ECMAScript 3的引擎上实现了ECMAScript 5的新特性,而且在Node.js上和在浏览器上有完全相同的表现。因为它能在Node.js上使用,不光浏览器上,所以它不是polyfill。)</p>
<p>在旧版本的浏览器中，使用eval()对JSON 数据结构求值存在风险，因为可能会执行一些恶意代码。<br>所以对于不能原生支持JSON 解析的浏览器，使用这个shim 是最佳选择。</p>
<p>JSON 对象有两个方法：stringify()和parse()。<br>在最简单的情况下，这两个方法分别用于把JavaScript 对象序列化为JSON 字符串和把JSON 字符串解析为原生JavaScript 值。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> book = &#123;</div><div class="line">    title: <span class="string">"Professional JavaScript"</span>,</div><div class="line">    authors: [</div><div class="line">        <span class="string">"Nicholas C. Zakas"</span></div><div class="line">    ],</div><div class="line">    edition: <span class="number">3</span>,</div><div class="line">    year: <span class="number">2011</span></div><div class="line">&#125;;</div><div class="line"><span class="keyword">var</span> jsonText = <span class="built_in">JSON</span>.stringify(book);</div></pre></td></tr></table></figure>
<p>使用JSON.stringify()把一个JavaScript 对象序列化为一个JSON 字符串，然后将它保存在变量jsonText 中。<br>默认情况下，JSON.stringify()输出的JSON 字符串不包含任何空格字符或缩进。<br><code>{&quot;title&quot;:&quot;Professional JavaScript&quot;,&quot;authors&quot;:[&quot;Nicholas C. Zakas&quot;],&quot;edition&quot;:3,&quot;year&quot;:2011}</code><br>在序列化JavaScript 对象时，所有函数及原型成员都会被有意忽略，不体现在结果中。值为undefined 的任何属性也都会被跳过。结果中最终都是值为有效JSON 数据类型的实例属性。<br>将JSON 字符串直接传递给JSON.parse()就可以得到相应的JavaScript 值。<br><code>var bookCopy = JSON.parse(jsonText);</code><br>虽然book 与bookCopy 具有相同的属性，但它们是两个独立的、没有任何关系的对象。<br>如果传给JSON.parse()的字符串不是有效的JSON，该方法会抛出错误。</p>
<h3 id="序列化选项"><a href="#序列化选项" class="headerlink" title="序列化选项"></a>序列化选项</h3><p>JSON.stringify()除了要序列化的JavaScript 对象外，还可以接收另外两个参数，这两个参数用于指定以不同的方式序列化JavaScript 对象。<br>第一个参数是个过滤器，可以是一个数组，也可以是一个函数；<br>第二个参数是一个选项，表示是否在JSON 字符串中保留缩进。<br>单独或组合使用这两个参数，可以更全面深入地控制JSON 的序列化。</p>
<h4 id="过滤结果"><a href="#过滤结果" class="headerlink" title="过滤结果"></a>过滤结果</h4><p>如果过滤器参数是数组，那么JSON.stringify()的结果中将只包含数组中列出的属性。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> book = &#123;</div><div class="line">    <span class="string">"title"</span>: <span class="string">"Professional JavaScript"</span>,</div><div class="line">    <span class="string">"authors"</span>: [</div><div class="line">        <span class="string">"Nicholas C. Zakas"</span></div><div class="line">    ],</div><div class="line">    edition: <span class="number">3</span>,</div><div class="line">    year: <span class="number">2011</span></div><div class="line">&#125;;</div><div class="line"><span class="keyword">var</span> jsonText = <span class="built_in">JSON</span>.stringify(book, [<span class="string">"title"</span>, <span class="string">"edition"</span>]);</div></pre></td></tr></table></figure>
<p>JSON.stringify()的第二个参数是一个数组，其中包含两个字符串：”title”和”edition”。<br>这两个属性与将要序列化的对象中的属性是对应的，因此在返回的结果字符串中，就只会包含这两个属性：<br><code>{&quot;title&quot;:&quot;Professional JavaScript&quot;,&quot;edition&quot;:3}</code></p>
<p>如果第二个参数是函数，行为会稍有不同。传入的函数接收两个参数，属性（键）名和属性值。<br>根据属性（键）名可以知道应该如何处理要序列化的对象中的属性。<br>属性名只能是字符串，而在值并非键值对结构的值时，键名可以是空字符串。<br>为了改变序列化对象的结果，函数返回的值就是相应键的值。不过要注意，如果函数返回了undefined，那么相应的属性会被忽略。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> book = &#123;</div><div class="line">    <span class="string">"title"</span>: <span class="string">"Professional JavaScript"</span>,</div><div class="line">    <span class="string">"authors"</span>: [</div><div class="line">        <span class="string">"Nicholas C. Zakas"</span></div><div class="line">    ],</div><div class="line">    edition: <span class="number">3</span>,</div><div class="line">    year: <span class="number">2011</span></div><div class="line">&#125;;</div><div class="line"><span class="keyword">var</span> jsonText = <span class="built_in">JSON</span>.stringify(book, <span class="function"><span class="keyword">function</span>(<span class="params">key, value</span>) </span>&#123;</div><div class="line">    <span class="keyword">switch</span> (key) &#123;</div><div class="line">        <span class="keyword">case</span> <span class="string">"authors"</span>:</div><div class="line">            <span class="keyword">return</span> value.join(<span class="string">","</span>)</div><div class="line">        <span class="keyword">case</span> <span class="string">"year"</span>:</div><div class="line">            <span class="keyword">return</span> <span class="number">5000</span>;</div><div class="line">        <span class="keyword">case</span> <span class="string">"edition"</span>:</div><div class="line">            <span class="keyword">return</span> <span class="literal">undefined</span>;</div><div class="line">        <span class="keyword">default</span>:</div><div class="line">            <span class="keyword">return</span> value;</div><div class="line">    &#125;</div><div class="line">&#125;);</div></pre></td></tr></table></figure>
<p>函数过滤器根据传入的键来决定结果。<br>如果键为”authors”，就将数组连接为一个字符串；<br>如果键为”year”，则将其值设置为5000；<br>如果键为”edition”，通过返回undefined 删除该属性。<br>最后，一定要提供default 项，此时返回传入的值，以便其他值都能正常出现在结果中。</p>
<p>实际上，第一次调用这个函数过滤器，传入的键是一个空字符串，而值就是book 对象。<br>序列化后的JSON 字符串:<code>{&quot;title&quot;:&quot;Professional JavaScript&quot;,&quot;authors&quot;:&quot;Nicholas C. Zakas&quot;,&quot;year&quot;:5000}</code><br>要序列化的对象中的每一个对象都要经过过滤器，因此数组中的每个带有这些属性的对象经过过滤之后，每个对象都只会包含”title”、”authors”和”year”属性。</p>
<h4 id="字符串缩进"><a href="#字符串缩进" class="headerlink" title="字符串缩进"></a>字符串缩进</h4><p>JSON.stringify()方法的第三个参数用于控制结果中的缩进和空白符。<br>如果这个参数是一个数值，那它表示的是每个级别缩进的空格数。<br>例如，要在每个级别缩进4 个空格:<code>var jsonText = JSON.stringify(book, null, 4);</code><br>结果：</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">&#123;</div><div class="line">    <span class="attr">"title"</span>: <span class="string">"Professional JavaScript"</span>,</div><div class="line">    <span class="attr">"authors"</span>: [</div><div class="line">        <span class="string">"Nicholas C. Zakas"</span></div><div class="line">    ],</div><div class="line">    <span class="attr">"edition"</span>: <span class="number">3</span>,</div><div class="line">    <span class="attr">"year"</span>: <span class="number">2011</span></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>JSON.stringify()也在结果字符串中插入了换行符以提高可读性。<br>只要传入有效的控制缩进的参数值，结果字符串就会包含换行符。（只缩进而不换行意义不大。）<br>最大缩进空格数为10，所有大于10 的值都会自动转换为10。</p>
<p>如果缩进参数是一个字符串而非数值，则这个字符串将在JSON 字符串中被用作缩进字符（不再使用空格）。<br>在使用字符串的情况下，可以将缩进字符设置为制表符，或者两个短划线之类的任意字符。<br><code>var jsonText = JSON.stringify(book, null, &quot; --&quot;);</code></p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">&#123;</div><div class="line">--"title": "Professional JavaScript",</div><div class="line">--"authors": [</div><div class="line">----"Nicholas C. Zakas"</div><div class="line">--],</div><div class="line">--"edition": 3,</div><div class="line">--"year": 2011</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h4 id="toJSON-方法"><a href="#toJSON-方法" class="headerlink" title="toJSON()方法"></a>toJSON()方法</h4><p>有时候，JSON.stringify()还是不能满足对某些对象进行自定义序列化的需求。<br>在这些情况下，可以给对象定义toJSON()方法，返回其自身的JSON 数据格式。<br>原生Date 对象有一个toJSON()方法，能够将JavaScript 的Date 对象自动转换成ISO 8601 日期字符串<br>（与在Date 对象上调用toISOString()的结果完全一样）。<br>可以为任何对象添加toJSON()方法:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> book = &#123;</div><div class="line">    <span class="string">"title"</span>: <span class="string">"Professional JavaScript"</span>,</div><div class="line">    <span class="string">"authors"</span>: [</div><div class="line">        <span class="string">"Nicholas C. Zakas"</span></div><div class="line">    ],</div><div class="line">    edition: <span class="number">3</span>,</div><div class="line">    year: <span class="number">2011</span>,</div><div class="line">    toJSON: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</div><div class="line">        <span class="keyword">return</span> <span class="keyword">this</span>.title;</div><div class="line">    &#125;</div><div class="line">&#125;;</div><div class="line"><span class="keyword">var</span> jsonText = <span class="built_in">JSON</span>.stringify(book);</div></pre></td></tr></table></figure>
<p>与Date 对象类似，这个对象也将被序列化为一个简单的字符串而非对象。<br>可以让toJSON()方法返回任何值，它都能正常工作。<br>比如，可以让这个方法返回undefined，此时如果这个对象嵌入在另一个对象中，会导致它的值变成null，而如果它是顶级对象，结果就是undefined。</p>
<p>toJSON()可以作为函数过滤器的补充，因此理解序列化的内部顺序十分重要。<br>假设把一个对象传入JSON.stringify()，序列化该对象的顺序如下:</p>
<p>(1) 如果存在toJSON()方法而且能通过它取得有效的值，则调用该方法。否则，返回对象本身。<br>(2) 如果提供了第二个参数，应用这个函数过滤器。传入函数过滤器的值是第(1)步返回的值。<br>(3) 对第(2)步返回的每个值进行相应的序列化。<br>(4) 如果提供了第三个参数，执行相应的格式化。</p>
<p>无论是考虑定义toJSON()方法，还是考虑使用函数过滤器，亦或需要同时使用两者，理解这个顺序都是至关重要的。</p>
<h3 id="解析选项"><a href="#解析选项" class="headerlink" title="解析选项"></a>解析选项</h3><p>JSON.parse()方法也可以接收另一个参数，该参数是一个函数，将在每个键值对上调用。<br>为了区别JSON.stringify()接收的替换（过滤）函数（replacer），这个函数被称为还原函数（reviver），<br>但实际上这两个函数的签名是相同的——它们都接收两个参数，一个键和一个值，而且都需要返回一个值。<br>如果还原函数返回undefined，则表示要从结果中删除相应的键；如果返回其他值，则将该值插入到结果中。<br>在将日期字符串转换为Date 对象时，经常要用到还原函数。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> book = &#123;</div><div class="line">    <span class="string">"title"</span>: <span class="string">"Professional JavaScript"</span>,</div><div class="line">    <span class="string">"authors"</span>: [</div><div class="line">        <span class="string">"Nicholas C. Zakas"</span></div><div class="line">    ],</div><div class="line">    edition: <span class="number">3</span>,</div><div class="line">    year: <span class="number">2011</span>,</div><div class="line">    releaseDate: <span class="keyword">new</span> <span class="built_in">Date</span>(<span class="number">2011</span>, <span class="number">11</span>, <span class="number">1</span>)</div><div class="line">&#125;;</div><div class="line"><span class="keyword">var</span> jsonText = <span class="built_in">JSON</span>.stringify(book);</div><div class="line"><span class="keyword">var</span> bookCopy = <span class="built_in">JSON</span>.parse(jsonText, <span class="function"><span class="keyword">function</span>(<span class="params">key, value</span>) </span>&#123;</div><div class="line">    <span class="keyword">if</span> (key == <span class="string">"releaseDate"</span>) &#123;</div><div class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Date</span>(value);</div><div class="line">    &#125; <span class="keyword">else</span> &#123;</div><div class="line">        <span class="keyword">return</span> value;</div><div class="line">    &#125;</div><div class="line">&#125;);</div><div class="line">alert(bookCopy.releaseDate.getFullYear());</div></pre></td></tr></table></figure>
<p>先是为book 对象新增了一个releaseDate 属性，该属性保存着一个Date 对象。<br>这个对象在经过序列化之后变成了有效的JSON 字符串，<br>然后经过解析又在bookCopy 中还原为一个Date对象。<br>还原函数在遇到”releaseDate”键时，会基于相应的值创建一个新的Date 对象。<br>结果就是bookCopy.releaseDate 属性中会保存一个Date 对象。</p>

      
    </div>

    <div>
      
        

      
    </div>

    <div>
      
        

      
    </div>


    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/Web/" rel="tag"># Web</a>
          
            <a href="/tags/JavaScript/" rel="tag"># JavaScript</a>
          
        </div>
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2016/11/03/javascript-note-18-2/" rel="next" title="《 JavaScript 高级程序设计》备忘-第十八章-2">
                <i class="fa fa-chevron-left"></i> 《 JavaScript 高级程序设计》备忘-第十八章-2
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2016/11/04/javascript-note-21-1/" rel="prev" title="《 JavaScript 高级程序设计》备忘-第二十一章-1">
                《 JavaScript 高级程序设计》备忘-第二十一章-1 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          
  <div class="comments" id="comments">
    
  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/uploads/avatar.jpg"
               alt="Huang SJ" />
          <p class="site-author-name" itemprop="name">Huang SJ</p>
          <p class="site-description motion-element" itemprop="description"></p>
        </div>
        <nav class="site-state motion-element">
          <div class="site-state-item site-state-posts">
            <a href="/archives">
              <span class="site-state-item-count">75</span>
              <span class="site-state-item-name">日志</span>
            </a>
          </div>

          
            <div class="site-state-item site-state-categories">
              <a href="/categories">
                <span class="site-state-item-count">4</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            <div class="site-state-item site-state-tags">
              <a href="/tags">
                <span class="site-state-item-count">9</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        

        <div class="links-of-author motion-element">
          
            
              <span class="links-of-author-item">
                <a href="https://github.com/hsj1992" target="_blank" title="GitHub">
                  
                    <i class="fa fa-fw fa-github"></i>
                  
                  GitHub
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://twitter.com/hsj9527" target="_blank" title="Twitter">
                  
                    <i class="fa fa-fw fa-twitter"></i>
                  
                  Twitter
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://weibo.com/u/1694147905" target="_blank" title="Weibo">
                  
                    <i class="fa fa-fw fa-weibo"></i>
                  
                  Weibo
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://www.freecodecamp.cn/hsj1992" target="_blank" title="FreeCodeCamp">
                  
                    <i class="fa fa-fw fa-fire"></i>
                  
                  FreeCodeCamp
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://codepen.io/hsj1992/" target="_blank" title="codepen">
                  
                    <i class="fa fa-fw fa-codepen"></i>
                  
                  codepen
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://hsj1992.oschina.io/" target="_blank" title="码云镜像">
                  
                    <i class="fa fa-fw fa-code"></i>
                  
                  码云镜像
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://hsj1992.coding.me/" target="_blank" title="coding镜像">
                  
                    <i class="fa fa-fw fa-code"></i>
                  
                  coding镜像
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://hsj1992.github.io/" target="_blank" title="github镜像">
                  
                    <i class="fa fa-fw fa-code"></i>
                  
                  github镜像
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://codingme-6dd8a.firebaseapp.com" target="_blank" title="Firebase镜像">
                  
                    <i class="fa fa-fw fa-google"></i>
                  
                  Firebase镜像
                </a>
              </span>
            
          
        </div>

        
        

        
        

        


      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#JSON"><span class="nav-number">1.</span> <span class="nav-text">JSON</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#语法"><span class="nav-number">1.1.</span> <span class="nav-text">语法</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#简单值"><span class="nav-number">1.1.1.</span> <span class="nav-text">简单值</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#对象"><span class="nav-number">1.1.2.</span> <span class="nav-text">对象</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#数组"><span class="nav-number">1.1.3.</span> <span class="nav-text">数组</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#解析与序列化"><span class="nav-number">1.2.</span> <span class="nav-text">解析与序列化</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#JSON对象"><span class="nav-number">1.2.1.</span> <span class="nav-text">JSON对象</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#序列化选项"><span class="nav-number">1.2.2.</span> <span class="nav-text">序列化选项</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#过滤结果"><span class="nav-number">1.2.2.1.</span> <span class="nav-text">过滤结果</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#字符串缩进"><span class="nav-number">1.2.2.2.</span> <span class="nav-text">字符串缩进</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#toJSON-方法"><span class="nav-number">1.2.2.3.</span> <span class="nav-text">toJSON()方法</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#解析选项"><span class="nav-number">1.2.3.</span> <span class="nav-text">解析选项</span></a></li></ol></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy;  2015 - 
  <span itemprop="copyrightYear">2016</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Huang SJ</span>
</div>


<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.Pisces
  </a>
</div>


        

        
      </div>
    </footer>

    <div class="back-to-top">
      <i class="fa fa-arrow-up"></i>
    </div>
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  



  
  <script type="text/javascript" src="//cdn.staticfile.org/jquery/2.1.3/jquery.min.js"></script>

  
  <script type="text/javascript" src="//cdn.staticfile.org/fastclick/1.0.6/fastclick.min.js"></script>

  
  <script type="text/javascript" src="//cdn.staticfile.org/jquery_lazyload/1.9.7/jquery.lazyload.min.js"></script>

  
  <script type="text/javascript" src="//cdn.staticfile.org/velocity/1.2.1/velocity.min.js"></script>

  
  <script type="text/javascript" src="//cdn.staticfile.org/velocity/1.2.1/velocity.ui.min.js"></script>

  
  <script type="text/javascript" src="//cdn.staticfile.org/fancybox/2.1.5/jquery.fancybox.pack.js"></script>


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.0"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.0"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.0"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.0"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.0"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.0"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.0"></script>



  



  




	




  
  
  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    // Search DB path;
    var search_path = "search.xml";
    if (search_path.length == 0) {
      search_path = "search.xml";
    }
    var path = "/" + search_path;
    // monitor main search box;

    function proceedsearch() {
      $("body").append('<div class="popoverlay">').css('overflow', 'hidden');
      $('.popup').toggle();
    }
    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';
      $.ajax({
        url: path,
        dataType: "xml",
        async: true,
        success: function( xmlResponse ) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = $( "entry", xmlResponse ).map(function() {
            return {
              title: $( "title", this ).text(),
              content: $("content",this).text(),
              url: $( "url" , this).text()
            };
          }).get();
          var $input = document.getElementById(search_id);
          var $resultContent = document.getElementById(content_id);
          $input.addEventListener('input', function(){
            var matchcounts = 0;
            var str='<ul class=\"search-result-list\">';
            var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
            $resultContent.innerHTML = "";
            if (this.value.trim().length > 1) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var content_index = [];
                var data_title = data.title.trim().toLowerCase();
                var data_content = data.content.trim().replace(/<[^>]+>/g,"").toLowerCase();
                var data_url = decodeURIComponent(data.url);
                var index_title = -1;
                var index_content = -1;
                var first_occur = -1;
                // only match artiles with not empty titles and contents
                if(data_title != '') {
                  keywords.forEach(function(keyword, i) {
                    index_title = data_title.indexOf(keyword);
                    index_content = data_content.indexOf(keyword);
                    if( index_title >= 0 || index_content >= 0 ){
                      isMatch = true;
                      if (i == 0) {
                        first_occur = index_content;
                      }
                    }

                  });
                }
                // show search results
                if (isMatch) {
                  matchcounts += 1;
                  str += "<li><a href='"+ data_url +"' class='search-result-title'>"+ data_title +"</a>";
                  var content = data.content.trim().replace(/<[^>]+>/g,"");
                  if (first_occur >= 0) {
                    // cut out 100 characters
                    var start = first_occur - 20;
                    var end = first_occur + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if(start == 0){
                      end = 50;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    var match_content = content.substring(start, end);
                    // highlight all keywords
                    keywords.forEach(function(keyword){
                      var regS = new RegExp(keyword, "gi");
                      match_content = match_content.replace(regS, "<b class=\"search-keyword\">"+keyword+"</b>");
                    });

                    str += "<p class=\"search-result\">" + match_content +"...</p>"
                  }
                  str += "</li>";
                }
              })};
            str += "</ul>";
            if (matchcounts == 0) { str = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>' }
            if (keywords == "") { str = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>' }
            $resultContent.innerHTML = str;
          });
          proceedsearch();
        }
      });}

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched == false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(function(e){
      $('.popup').hide();
      $(".popoverlay").remove();
      $('body').css('overflow', '');
    });
    $('.popup').click(function(e){
      e.stopPropagation();
    });
  </script>


  

  

  

  


</body>
</html>
